<?php
namespace Monkey;

/**
 * 插件管理器\Monkey\PluginManager
 * @package    Monkey
 * @author     HuangYi
 * @copyright  Copyright (c) 2011-07-01——2013-03-30
 * @license    New BSD License
 * @version    $Id: \Monkey\PluginManager.php 版本号 2013-03-30 $
 */
final class PluginManager {
    private static $_instance;
    private static $_ini_file;
    /**
     * 插件注册表（总表）
     * @var array
     * array(
     *      'pluginname'  =>array(
     *                  'enable'    =>true, //是否启用插件
     *                  'isbefore'  =>true, //TRUE为前置插件，FALSE为后置插件
     *                  'controller'    =>'', //控制器名的正则匹配模式。例外，空字符串匹配任何控制器。
     *                  'route'      =>'', //路由的正则匹配模式。例外，空字符串匹配任何路由。
     *                  'callback'  =>'myclass::mymethod',//插件的回调方法，全静态形式
     *       ),
     * )
     */
    private static $_plugins;
    private function __construct() {
        self::$_ini_file = SYSTEM.'/config/plugin.ini.php';
        self::$_plugins = file_exists(self::$_ini_file) ?
            fileReadSerialize(self::$_ini_file) : array() ;//将来改为从数据库中读取（透过缓存）
    }
    private function __clone() { }
    public static function _instance(){
        !self::$_instance and self::$_instance=new self();
        return self::$_instance;
    }
    /**
     * 保存插件注册表
     */
    public function save(){
        fileSaveSerialize(self::$_ini_file, self::$_plugins);
    }
    /**
     * 添加插件
     * @param string $pluginName 插件名
     * @param string $pluginReg 插件注册表
     * @return bool
     */
    public function post($pluginName,$pluginReg){
        if(isset(self::$_plugins[$pluginName]))return false;
        self::$_plugins[$pluginName]=$pluginReg;
        return true;
    }
    /**
     * 读取插件
     * @param string $pluginName 插件名
     * @return array $plugin 插件注册项数组
     */
    public function get($pluginName){
        if(isset(self::$_plugins[$pluginName]))return self::$_plugins[$pluginName];
        return array();
    }
    /**
     * 移除插件
     * @param string $pluginName 插件名
     * @return bool
     */
    public function delete($pluginName){
        if(!isset(self::$_plugins[$pluginName]))return false;
        unset(self::$_plugins[$pluginName]);
        return true;
    }
    /**
     * 更新插件
     * @param string $pluginName 插件名
     * @param array $pluginReg 插件注册表
     * @return bool
     */
    public function put($pluginName,$pluginReg){
        if(!isset(self::$_plugins[$pluginName]))return false;
        self::$_plugins[$pluginName]=$pluginReg;
        return true;
    }
    /**
     * 运行前置插件
     * @param string $controller 控制器名
     * @param string $route 路由
     * @return bool
     */
    public function before($controller,$route){
        $result=true;
        foreach(self::$_plugins as $plugin){
            if(!$plugin['enable'])continue;
            if(!$plugin['isbefore'])continue;
            if($plugin['controller'] && !preg_match($plugin['controller'],$controller))continue;
            if($plugin['route']=='' or preg_match($plugin['route'],$route) ){
                !call_user_func($plugin['callback'],$route) and $result=false;
            }
        }
        return $result;
    }
    /**
     * 运行后置插件
     * @param string $controller 控制器名
     * @param string $route 路由
     */
    public function after($controller,$route){
        foreach(self::$_plugins as $plugin){
            if(!$plugin['enable'])continue;
            if($plugin['isbefore'])continue;
            if($plugin['controller'] && !preg_match($plugin['controller'],$controller))continue;
            if($plugin['route']=='*' or preg_match($plugin['route'],$route) ){
                call_user_func($plugin['callback']);
            }
        }
    }
}